package com.itlong.cloud.property.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.itlong.cloud.POJO.DTO.property.*;
import com.itlong.cloud.POJO.PO.AppUserInfoPO;
import com.itlong.cloud.constants.RabbitMQConstant;
import com.itlong.cloud.enumerate.AppUserRoomStatusEnum;
import com.itlong.cloud.property.dao.IPropertyAppUserInfoDao;
import com.itlong.cloud.property.dao.IPropertyAppUserRoomDao;
import com.itlong.cloud.property.service.IPropertyHouseHoldDeviceAuthService;
import com.itlong.cloud.property.service.IPropertyHouseHoldInfoService;
import com.itlong.cloud.property.service.IPropertyUserService;
import com.itlong.cloud.rabbitmq.config.MessageSender;
import com.itlong.cloud.utils.node.JsonUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.*;

/**
 * <desc>
 *      操作住户设备权限接口实现类
 * </desc>
 *
 * @createDate 2017/10/18
 */
@Service
public class PropertyHouserHoldDeviceAuthServiceImpl implements IPropertyHouseHoldDeviceAuthService {
    private static final Logger LOG = LoggerFactory.getLogger(PropertyHouserHoldDeviceAuthServiceImpl.class);

    @Autowired
    private IPropertyAppUserRoomDao iPropertyAppUserRoomDao;      //App用户房间信息数据库访问对象

    //物业-人员信息业务处理接口
    @Autowired
    private IPropertyUserService iPropertyUserService;

    @Autowired
    private IPropertyHouseHoldInfoService iPropertyHouseHoldInfoService;

    //消息队列
    @Autowired
    private MessageSender messageSender;

    @Autowired
    private IPropertyAppUserInfoDao iPropertyAppUserInfoDao;



    /**
     * <desc>
     *      获取某个标识在一段字符串中出现的次数
     * <desc/>
     *
     * @param string 需要检测的字符串
     * @param sign 需要检测的标识
     * @return int 数目
     * @author zhangs
     * @createDate 2017/10/10
     */
    private int getIndex(String string, String sign) {
        int index = 0;
        for(int j = 0;j < string.length();j++) {
            if(StringHandlerUtil.compareStrWithOutEmpty(sign, String.valueOf(string.charAt(j)))) {
                index++;
            }
        }
        return index;
    }

    /**
     * <desc>
     *      用户设备权限-获取用户权限地址
     * <desc/>
     *
     * @param userIdLists 权限变更的用户Id和对应项目Id的集合,key:userId和projectId
     * @param projectId 项目Id
     * @param loginUserId 用户登录Id
     * @return List<UserDeviceAuthAddreddDTO> 用户权限地址数据传输对象集
     * @author zhangs
     * @createDate 2017/10/13
     */
    @Override
    public List<UserDeviceAuthAddreddDTO> getUserAuthAddr(List<Map<String, Object>> userIdLists, String projectId, String loginUserId) {
        if(StringUtils.isBlank(loginUserId)) {
            loginUserId = iPropertyUserService.getPropertyAdmin(projectId);
        }
        List<UserDeviceAuthAddreddDTO> userDeviceAuthAddreddDTOS = new ArrayList<>();
        if(userIdLists == null || userIdLists.size() == 0) {
            return userDeviceAuthAddreddDTOS;
        }

        //Map组成：("userIds",List<String>)和("projectId",projectId)和("userRoomStatus",userRoomStatus)
        Map<String, Object> params = new HashMap<>();
        List<String> userList = new ArrayList<>();
        Set<String> userIdSet = new HashSet<>();
        for (Map<String, Object> userIdList:userIdLists) {
            String userId = (String) userIdList.get("userId");
            userList.add(userId);
            userIdSet.add(userId);
        }
        params.put("userIds", userList);
        params.put("projectId",projectId);
        params.put("userRoomStatus",AppUserRoomStatusEnum.USERROOM_STATUS_MOVEIN.getType());
        //一次查出所有住户及住户有权限的地址，再按各住户整理，最后打包处理
        List<UserAuthRoomAddrDTO> userAuthRoomAddrDTOLists = iPropertyAppUserRoomDao.getUserAuthAddress(params);
        Map<String, List<UserAuthRoomAddrDTO>> userAuthRoomAddrDTOMap = new HashMap<>();
        if (userAuthRoomAddrDTOLists != null && userAuthRoomAddrDTOLists.size() > 0) {
            //按各住户整理
            for (UserAuthRoomAddrDTO userAuthRoomAddrDTO : userAuthRoomAddrDTOLists) {
                String userId = userAuthRoomAddrDTO.getUserId();
                List<UserAuthRoomAddrDTO> list = userAuthRoomAddrDTOMap.get(userId);
                if (list == null) {
                    list = new ArrayList<>();
                    list.add(userAuthRoomAddrDTO);
                } else {
                    list.add(userAuthRoomAddrDTO);
                }
                userAuthRoomAddrDTOMap.put(userId, list);
            }
        }
        //打包处理
        for (String userId:userIdSet) {
            List<UserAuthRoomAddrDTO> userAuthRoomAddrDTOListOneUser = userAuthRoomAddrDTOMap.get(userId);
            //住户在当前小区有地址
            if(userAuthRoomAddrDTOListOneUser != null && userAuthRoomAddrDTOListOneUser.size() > 0) {
                //合并用户设备权限地址
                List<UserAuthRoomAddrDTO> userAuthRoomAddrDTOList = new ArrayList<>();
                userAuthRoomAddrDTOList.add(userAuthRoomAddrDTOListOneUser.get(0));
                if(userAuthRoomAddrDTOListOneUser.size() == 1) {
                    //仅有一条数据
                    userDeviceAuthAddreddDTOS.add(this.mergeUserDeviceAuthAddr(userAuthRoomAddrDTOList, projectId, loginUserId));
                } else {
                    //有多条数据，遍历，合并相同用户的设备权限地址
                    for(int index = 1;index < userAuthRoomAddrDTOListOneUser.size();index++) {
                        if(StringHandlerUtil.compareStrWithOutEmpty(userId, userAuthRoomAddrDTOListOneUser.get(index).getUserId())) {
                            userAuthRoomAddrDTOList.add(userAuthRoomAddrDTOListOneUser.get(index));
                        } else {
                            userDeviceAuthAddreddDTOS.add(this.mergeUserDeviceAuthAddr(userAuthRoomAddrDTOList, projectId, loginUserId));
                            userAuthRoomAddrDTOList = new ArrayList<>();
                            userAuthRoomAddrDTOList.add(userAuthRoomAddrDTOListOneUser.get(index));
                            userId = userAuthRoomAddrDTOListOneUser.get(index).getUserId();
                        }
                        if(index == userAuthRoomAddrDTOListOneUser.size() - 1) {
                            userDeviceAuthAddreddDTOS.add(this.mergeUserDeviceAuthAddr(userAuthRoomAddrDTOList, projectId, loginUserId));
                        }
                    }
                }
            } else {
                //住户在当前小区无地址,需清除住户在物业中的权限
                UserDeviceAuthAddreddDTO userDeviceAuthAddreddDTO = new UserDeviceAuthAddreddDTO();
                userDeviceAuthAddreddDTO.setAuthUserId(loginUserId);
                userDeviceAuthAddreddDTO.setProjectId(projectId);
                userDeviceAuthAddreddDTO.setUserId(userId);
                AppUserInfoPO appUserInfoPO = new AppUserInfoPO();
                appUserInfoPO.setUserId(userId);
                appUserInfoPO = iPropertyAppUserInfoDao.getOne(appUserInfoPO);
                if (appUserInfoPO != null) {
                    //未注册用户(无password)不需极光推送
                    String password = appUserInfoPO.getPassword();
                    String phoneNum = "";
                    if (StringUtils.isNotEmpty(password)) {
                        phoneNum = appUserInfoPO.getPhoneNum();
                    }
                    userDeviceAuthAddreddDTO.setPhoneNum(phoneNum);
                    userDeviceAuthAddreddDTOS.add(userDeviceAuthAddreddDTO);
                }
            }
        }

        return userDeviceAuthAddreddDTOS;
    }

    /**
     * <desc>
     *      合并用户设备权限地址
     * <desc/>
     *
     * @param userAuthRoomAddrDTOS 用户设备权限对应的房间地址
     * @param projectId 项目Id
     * @param loginUserId 用户登录Id
     * @return List<UserDeviceAuthAddreddDTO> 用户权限地址数据传输对象集
     * @author zhangs
     * @createDate 2017/10/13
     */
    private UserDeviceAuthAddreddDTO mergeUserDeviceAuthAddr(
            List<UserAuthRoomAddrDTO> userAuthRoomAddrDTOS, String projectId, String loginUserId) {
        //用户拥有的房间地址集合 eg:{"buildId001":{"unitId01":"1001,1301","unitId03":"0703,0905"}}
        Map<String, Object> userAuthRoomAddrMap = new HashMap<>();
        Map<String, Object> unitMap = new HashMap<>();
        UserDeviceAuthAddreddDTO userDeviceAuthAddreddDTO = new UserDeviceAuthAddreddDTO();

        if (userAuthRoomAddrDTOS.size() > 0) {
            UserAuthRoomAddrDTO userAuthRoomAddrDTO = userAuthRoomAddrDTOS.get(0);
            String userId = userAuthRoomAddrDTO.getUserId();
            StringBuffer roomNums = new StringBuffer(userAuthRoomAddrDTO.getRoomNum());
            roomNums.append(",");
            String buildId = userAuthRoomAddrDTO.getBuildId();
            String unitId = userAuthRoomAddrDTO.getUnitId();
            unitMap.put(unitId, StringHandlerUtil.clearComma(roomNums).toString());
            unitMap.put(unitId+roomNums,userAuthRoomAddrDTO.getLiftDoorType());
            userAuthRoomAddrMap.put(buildId, unitMap);
            if(userAuthRoomAddrDTOS.size() == 1) {
                //只有一条房间数据
                unitMap.put(unitId, StringHandlerUtil.clearComma(roomNums).toString());
                userAuthRoomAddrMap.put(buildId, unitMap);
            } else {
                //有多条数据
                for (int i = 1; i < userAuthRoomAddrDTOS.size(); i++) {
                    if (!StringHandlerUtil.compareStrWithOutEmpty(userAuthRoomAddrDTOS.get(i-1).getBuildId(), userAuthRoomAddrDTOS.get(i).getBuildId())) {
                        Map<String,Object> uMap = userAuthRoomAddrMap.get( userAuthRoomAddrDTOS.get(i).getBuildId()) != null ?
                                (HashMap)userAuthRoomAddrMap.get( userAuthRoomAddrDTOS.get(i).getBuildId()) : null;
                        unitId = userAuthRoomAddrDTOS.get(i).getUnitId();
                        if(uMap == null){
                            unitMap = new HashMap<>();
                        }else{
                            unitMap = uMap;
                        }
                        String uid = unitMap.get(unitId) != null ? unitMap.get(unitId).toString() : null;
                        roomNums = new StringBuffer(userAuthRoomAddrDTOS.get(i).getRoomNum());
                        if(StringUtils.isNotBlank(uid)){
                            uid = uid + "," + roomNums.toString();
                        }else{
                            uid = roomNums.toString();
                        }
                        unitMap.put(unitId, uid);
                        if(uMap == null){
                            userAuthRoomAddrMap.put(userAuthRoomAddrDTOS.get(i).getBuildId(), unitMap);
                        }
                    } else {
                        unitId = userAuthRoomAddrDTOS.get(i).getUnitId();
                        String uid = unitMap.get(unitId) != null ? unitMap.get(unitId).toString() : null;
                        roomNums = new StringBuffer(userAuthRoomAddrDTOS.get(i).getRoomNum());
                        if(StringUtils.isNotBlank(uid)){
                            uid = uid + "," + roomNums.toString();
                        }else{
                            uid = roomNums.toString();
                        }
                        unitMap.put(unitId, uid);
                    }
                    unitMap.put(unitId+roomNums,userAuthRoomAddrDTOS.get(i).getLiftDoorType());
                }
            }

            userDeviceAuthAddreddDTO =
                    new UserDeviceAuthAddreddDTO(userId, projectId, userAuthRoomAddrMap, null);
            userDeviceAuthAddreddDTO.setAuthUserId(loginUserId);
        }
        return userDeviceAuthAddreddDTO;
    }

    /**
     * <desc>
     *      迁出住户时删除地址对应的其他类别的设备权限
     * <desc/>
     *
     * @param  appUserUpdateUserRoomStatusDTO 迁出App用户传输数据
     * @param  projectId 项目Id
     * @return
     * @author zhangs
     * @createDate 2017/11/2
     */
    @Override
    public void delUserOtherAuth(AppUserUpdateUserRoomStatusDTO appUserUpdateUserRoomStatusDTO, String projectId) {
        List<UserDeviceAuthAddreddDTO> userDeviceAuthAddreddDTOS = new ArrayList<>();
        List<AppUsersRemoveDTO> appUsersRemoveDTOList = appUserUpdateUserRoomStatusDTO.getAppUsersRemoveDTOList();
        if(appUsersRemoveDTOList.size() == 0) {
            return;
        } else {
            for(AppUsersRemoveDTO appUsersRemoveDTO:appUsersRemoveDTOList) {
                String userId = appUsersRemoveDTO.getUserId();
                List<AppUserRoomDTO> appUserRoomDTOS = appUsersRemoveDTO.getAppUserRoomDTOS();
                if (!appUserRoomDTOS.isEmpty()) {
                    Map<String, Object> userAuthRoomAddrMap = new HashMap<>();  //用户拥有的房间地址集合
                    Map<String, Object> unitMap = new HashMap<>();
                    StringBuffer roomNums = new StringBuffer(appUserRoomDTOS.get(0).getRoomNum());
                    StringBuffer buildId = new StringBuffer(appUserRoomDTOS.get(0).getBuildId());
                    StringBuffer unitId = new StringBuffer(appUserRoomDTOS.get(0).getUnitId());
                    if (appUserRoomDTOS.size() == 1) {
                        //一条地址数据
                        unitMap.put(unitId.toString(), roomNums);
                        userAuthRoomAddrMap.put(buildId.toString(), unitMap);
                    } else {
                        //多条地址数据
                        for (int index = 1; index < appUserRoomDTOS.size(); index++) {
                            if (!buildId.toString().equals(appUserRoomDTOS.get(index).getBuildId())) {
                                unitMap.put(unitId.toString(), roomNums.toString());
                                userAuthRoomAddrMap.put(buildId.toString(), unitMap);

                                roomNums = new StringBuffer(appUserRoomDTOS.get(index).getRoomNum());
                                buildId = new StringBuffer(appUserRoomDTOS.get(index).getBuildId());
                                unitId = new StringBuffer(appUserRoomDTOS.get(index).getUnitId());
                                unitMap = new HashMap<>();
                            } else {
                                if (!unitId.toString().equals(appUserRoomDTOS.get(index).getUnitId())) {
                                    unitMap.put(unitId.toString(), roomNums.toString());
                                } else {
                                    roomNums.append(appUserRoomDTOS.get(index).getRoomNum());
                                }
                            }
                            if (index == appUserRoomDTOS.size() - 1) {
                                unitMap.put(unitId.toString(), roomNums.toString());
                                userAuthRoomAddrMap.put(buildId.toString(), unitMap);
                            }
                        }
                    }

                    UserDeviceAuthAddreddDTO userDeviceAuthAddreddDTO =
                            new UserDeviceAuthAddreddDTO(userId, projectId, userAuthRoomAddrMap, null);
                    userDeviceAuthAddreddDTOS.add(userDeviceAuthAddreddDTO);
                }
            }
        }
        try {
            //rabbitmq 发送任务
            //LOG.info("RabbitMQ_迁出住户时删除地址对应的其他类别的设备权限_生产者:" + JSON.toJSONString(userDeviceAuthAddreddDTOS));
            UserDeviceAuthAddressDTO userDeviceAuthAddressDTO = new UserDeviceAuthAddressDTO();
            userDeviceAuthAddressDTO.setUserDeviceAuthAddreddDTOS(userDeviceAuthAddreddDTOS);
            JSONObject dataJs = new JSONObject();
            dataJs.put("data", JsonUtil.toJSON(userDeviceAuthAddressDTO));
            messageSender.send(RabbitMQConstant.RABBITMQ_USER_REMOVE_DEVICE_AUTH_BY_ADDR_QUEUE,
                    JSON.toJSONString(dataJs), RabbitMQConstant.RABBITMQ_EQUIP_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_USER_REMOVE_DEVICE_AUTH_BY_ADDR_ROUTING_KEY);
        } catch (Exception e) {
            //回滚当前事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
    }
}
